package com.css.upms.api.vo;

import com.css.common.core.constent.CommonConstant;
import com.css.common.core.utils.tree.TreeNode;
import com.css.upms.api.dto.DeptTree;
import com.css.upms.api.dto.MenuTree;
import com.css.upms.api.entity.SysDept;
import com.css.upms.api.entity.SysMenu;
import lombok.experimental.UtilityClass;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * TreeUtil
 *
 * @author hanyx
 * @date 2019/05/03
 */
@UtilityClass
public class TreeUtil {
    /**
     * 两层循环实现建树
     *
     * @param treeNodes 传入的树节点列表
     * @return
     */
    public <T extends TreeNode> List<T> buildByLoop(List<T> treeNodes, Object root) {

        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (StringUtils.equalsIgnoreCase((String) root, treeNode.getParentId())) {
                trees.add(treeNode);
            }

            for (T it : treeNodes) {
                if (StringUtils.equalsIgnoreCase(it.getParentId(), treeNode.getId())) {
                    if (treeNode.getChildren() == null) {
                        treeNode.setChildren(new ArrayList<>());
                    }
                    treeNode.add(it);
                }
            }
        }
        return trees;
    }

    /**
     * 使用递归方法建树
     *
     * @param treeNodes
     * @return
     */
    public <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes, Object root) {
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (StringUtils.equalsIgnoreCase((String) root, treeNode.getParentId())) {
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    public <T extends TreeNode> T findChildren(T treeNode, List<T> treeNodes) {
        for (T it : treeNodes) {
            if (StringUtils.equalsIgnoreCase(it.getParentId(), treeNode.getId())) {
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    /**
     * 通过sysMenu创建树形节点
     *
     * @param menus
     * @param root
     * @return
     */
    public List<MenuTree> buildTree(List<SysMenu> menus, String root) {
        List<MenuTree> trees = buildMenuLIst(menus);
        return TreeUtil.buildByRecursive(trees, root);
    }

    public List<MenuTree> buildMenuLIst(List<SysMenu> menus) {
        List<MenuTree> trees = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(menus)) {
            MenuTree node;
            for (SysMenu menu : menus) {
                node = new MenuTree();
                node.setId(menu.getMenuId());
                node.setParentId(menu.getParentId());
                node.setName(menu.getMenuName());
                node.setTitle(menu.getMenuName());
                node.setUrl(menu.getUrl());
                node.setPermission(menu.getPermission());
                node.setLabel(menu.getMenuName());
                node.setComponent(menu.getComponent());
                node.setIcon(menu.getIcon());
                node.setType(menu.getMenuType());
                node.setSort(menu.getOrderNum());
                trees.add(node);
            }
        }
        return trees;
    }

    public List<DeptTree> buildDeptIst(List<SysDept> depts) {
        List<DeptTree> trees = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(depts)) {
            for (SysDept dept : depts) {
                trees.add(parseDetpTree(dept));
            }
        }
        return trees;
    }


    /**
     * 获取指定节点的父节点ID集合
     *
     * @param id        指定节点id
     * @param parentIds 父节点集合
     * @param group     Map<子节点id, 父节点id>
     */
    public void parentNodeIds(String id, Set<String> parentIds, Map<String, String> group) {
        if (MapUtils.isNotEmpty(group)) {
            if (group.containsKey(id)) {
                String parentId = group.get(id);
                // 父节点不是根节点进入递归
                if (!StringUtils.equals(parentId, CommonConstant.ROOT_NODE_VAL)) {
                    parentIds.add(parentId);
                    parentNodeIds(parentId, parentIds, group);
                }
            }
        }
    }

    /**
     * 获取指定节点的子节点ID集合
     *
     * @param id       指定节点id
     * @param childSet 子节点集合
     * @param group    Map<父节点id, List<子节点id>>
     */
    public void childNodeIds(String id, Set<String> childSet, Map<String, List<String>> group) {
        if (MapUtils.isNotEmpty(group)) {
            if (group.containsKey(id)) {
                List<String> childIds = group.get(id);
                // 不存在子节点退出递归
                for (String childId : childIds) {
                    if (group.containsKey(childId)) {
                        childSet.addAll(group.get(childId));
                        childNodeIds(childId, childSet, group);
                    }
                }
            }
        }
    }

    public DeptTree parseDetpTree(SysDept dept) {
        DeptTree node = new DeptTree();
        node.setId(dept.getDeptId());
        node.setParentId(dept.getParentId());
        node.setTitle(dept.getDeptName());
        node.setName(dept.getDeptName());
        node.setContact(dept.getContact());
        node.setDeptAddr(dept.getDeptAddr());
        node.setStatus(dept.getStatus());
        node.setPhone(dept.getPhone());
        return node;
    }

}
